/**
 * ESP32 调试器类
 * 负责集成WebGDB，处理调试信号，支持断点设置、寄存器查看、变量监视、单步执行
 */

export class Debugger {
    constructor(state, ui) {
        this.state = state;
        this.ui = ui;
        this.isConnected = false;
        this.isDebugging = false;
        this.breakpoints = new Map(); // 断点映射
        this.variables = new Map();   // 变量监视
        this.registers = {};          // 寄存器状态
        this.executionPath = [];      // 执行路径
        this.debugReport = null;      // 调试报告
        this.serialPort = null;
        this.reader = null;
        this.writer = null;
    }

    /**
     * 连接到设备进行调试
     */
    async connect() {
        if (!navigator.serial) {
            throw new Error('Web Serial API 不受支持，请使用最新版 Chrome 浏览器');
        }

        try {
            // 请求串口连接
            this.serialPort = await navigator.serial.requestPort({
                filters: [{ usbVendorId: 0x10c4, usbProductId: 0xea60 }] // CP210x 默认 VID/PID
            });

            // 打开串口连接
            await this.serialPort.open({ baudRate: 115200 });

            // 获取读写流
            this.reader = this.serialPort.readable.getReader();
            this.writer = this.serialPort.writable.getWriter();

            this.isConnected = true;
            this.ui.showAlert('调试器连接成功', 'success');
            
            // 启动数据读取循环
            this.startReading();
            
            return true;
        } catch (error) {
            this.isConnected = false;
            throw new Error(`连接失败: ${error.message}`);
        }
    }

    /**
     * 断开调试连接
     */
    async disconnect() {
        if (this.reader) {
            await this.reader.cancel();
            this.reader = null;
        }
        
        if (this.writer) {
            await this.writer.close();
            this.writer = null;
        }
        
        if (this.serialPort) {
            await this.serialPort.close();
            this.serialPort = null;
        }
        
        this.isConnected = false;
        this.isDebugging = false;
        this.ui.showAlert('调试器已断开连接', 'info');
    }

    /**
     * 启动数据读取循环
     */
    async startReading() {
        try {
            while (this.isConnected && this.reader) {
                const { value, done } = await this.reader.read();
                if (done) {
                    break;
                }
                
                // 处理接收到的数据
                const text = new TextDecoder().decode(value);
                this.handleDebugData(text);
            }
        } catch (error) {
            if (error.name !== 'AbortError') {
                console.error('读取调试数据时出错:', error);
                this.ui.showAlert(`读取调试数据时出错: ${error.message}`, 'error');
            }
        }
    }

    /**
     * 处理调试数据
     */
    handleDebugData(data) {
        // 解析GDB远程协议数据
        console.log('调试数据:', data);
        
        // 这里应该解析GDB远程协议数据
        // 简化实现，仅作为示例
        if (data.includes('(gdb)')) {
            this.ui.showAlert('GDB就绪', 'info');
        }
        
        // 将数据添加到串口监视器
        this.ui.appendToSerialMonitor(data, 'debug');
    }

    /**
     * 发送调试命令
     */
    async sendCommand(command) {
        if (!this.writer) {
            throw new Error('调试器未连接');
        }
        
        try {
            const encoder = new TextEncoder();
            await this.writer.write(encoder.encode(command + '\n'));
        } catch (error) {
            throw new Error(`发送命令失败: ${error.message}`);
        }
    }

    /**
     * 设置断点
     */
    async setBreakpoint(fileName, line) {
        if (!this.isDebugging) {
            throw new Error('调试未启动');
        }
        
        try {
            // 发送设置断点命令 (简化实现)
            const command = `b ${fileName}:${line}`;
            await this.sendCommand(command);
            
            // 记录断点
            const key = `${fileName}:${line}`;
            this.breakpoints.set(key, { fileName, line, active: true });
            
            this.ui.showAlert(`断点已设置在 ${fileName}:${line}`, 'success');
            return true;
        } catch (error) {
            this.ui.showAlert(`设置断点失败: ${error.message}`, 'error');
            return false;
        }
    }

    /**
     * 移除断点
     */
    async removeBreakpoint(fileName, line) {
        try {
            // 发送移除断点命令 (简化实现)
            const command = `clear ${fileName}:${line}`;
            await this.sendCommand(command);
            
            // 移除断点记录
            const key = `${fileName}:${line}`;
            this.breakpoints.delete(key);
            
            this.ui.showAlert(`断点已移除在 ${fileName}:${line}`, 'info');
            return true;
        } catch (error) {
            this.ui.showAlert(`移除断点失败: ${error.message}`, 'error');
            return false;
        }
    }

    /**
     * 启动调试
     */
    async startDebugging() {
        if (!this.isConnected) {
            await this.connect();
        }
        
        try {
            // 发送启动调试命令
            await this.sendCommand('target remote /dev/ttyUSB0');
            await this.sendCommand('monitor reset halt');
            
            this.isDebugging = true;
            this.executionPath = [];
            this.variables.clear();
            this.registers = {};
            
            this.ui.showAlert('调试已启动', 'success');
            this.ui.updateDebugStatus(true);
            
            return true;
        } catch (error) {
            this.ui.showAlert(`启动调试失败: ${error.message}`, 'error');
            return false;
        }
    }

    /**
     * 停止调试
     */
    async stopDebugging() {
        try {
            // 发送停止调试命令
            await this.sendCommand('detach');
            await this.sendCommand('quit');
            
            this.isDebugging = false;
            this.ui.showAlert('调试已停止', 'info');
            this.ui.updateDebugStatus(false);
            
            // 生成调试报告
            await this.generateDebugReport();
            
            return true;
        } catch (error) {
            this.ui.showAlert(`停止调试失败: ${error.message}`, 'error');
            return false;
        }
    }

    /**
     * 单步执行
     */
    async stepInto() {
        if (!this.isDebugging) {
            throw new Error('调试未启动');
        }
        
        try {
            await this.sendCommand('step');
            this.ui.showAlert('单步执行', 'info');
        } catch (error) {
            this.ui.showAlert(`单步执行失败: ${error.message}`, 'error');
        }
    }

    /**
     * 单步跳过
     */
    async stepOver() {
        if (!this.isDebugging) {
            throw new Error('调试未启动');
        }
        
        try {
            await this.sendCommand('next');
            this.ui.showAlert('单步跳过', 'info');
        } catch (error) {
            this.ui.showAlert(`单步跳过失败: ${error.message}`, 'error');
        }
    }

    /**
     * 继续执行
     */
    async continueExecution() {
        if (!this.isDebugging) {
            throw new Error('调试未启动');
        }
        
        try {
            await this.sendCommand('continue');
            this.ui.showAlert('继续执行', 'info');
        } catch (error) {
            this.ui.showAlert(`继续执行失败: ${error.message}`, 'error');
        }
    }

    /**
     * 获取变量值
     */
    async getVariableValue(variableName) {
        if (!this.isDebugging) {
            throw new Error('调试未启动');
        }
        
        try {
            // 发送打印变量命令
            await this.sendCommand(`print ${variableName}`);
            // 实际实现中需要解析返回值
            return `value_of_${variableName}`;
        } catch (error) {
            this.ui.showAlert(`获取变量值失败: ${error.message}`, 'error');
            return null;
        }
    }

    /**
     * 获取寄存器状态
     */
    async getRegisters() {
        if (!this.isDebugging) {
            throw new Error('调试未启动');
        }
        
        try {
            // 发送获取寄存器命令
            await this.sendCommand('info registers');
            // 实际实现中需要解析返回值
            return {
                pc: '0x40000000',
                sp: '0x3ffb0000',
                a0: '0x400d0000',
                a1: '0x3ffb1000'
            };
        } catch (error) {
            this.ui.showAlert(`获取寄存器状态失败: ${error.message}`, 'error');
            return {};
        }
    }

    /**
     * 添加到执行路径
     */
    addToExecutionPath(fileName, line) {
        this.executionPath.push({
            file: fileName,
            line: line,
            timestamp: new Date().toISOString()
        });
    }

    /**
     * 生成调试报告
     */
    async generateDebugReport() {
        try {
            // 获取寄存器状态
            this.registers = await this.getRegisters();
            
            // 生成调试报告
            this.debugReport = {
                projectName: this.state.getProjectName(),
                chipModel: this.state.getChipModel(),
                generatedAt: new Date().toISOString(),
                executionPath: this.executionPath,
                breakpoints: Array.from(this.breakpoints.values()),
                variables: Array.from(this.variables.entries()),
                registers: this.registers,
                resourceUsage: {
                    stackUsage: '未知',
                    heapUsage: '未知',
                    cpuUsage: '未知'
                },
                errors: [],
                warnings: [],
                recommendations: []
            };
            
            // 分析调试结果并生成建议
            this.analyzeDebugResults();
            
            this.ui.showAlert('调试报告已生成', 'success');
            return this.debugReport;
        } catch (error) {
            this.ui.showAlert(`生成调试报告失败: ${error.message}`, 'error');
            return null;
        }
    }

    /**
     * 分析调试结果
     */
    analyzeDebugResults() {
        if (!this.debugReport) return;
        
        // 检查GPIO配置冲突
        const pinConfigurations = this.state.getPinConfigurations();
        const conflicts = this.checkGPIOConflicts(pinConfigurations);
        if (conflicts.length > 0) {
            this.debugReport.warnings.push({
                type: 'GPIO冲突',
                description: '检测到GPIO引脚配置冲突',
                details: conflicts
            });
            
            this.debugReport.recommendations.push({
                type: 'GPIO优化',
                description: '建议重新配置GPIO引脚以避免冲突',
                action: '打开引脚配置面板并重新分配冲突的引脚'
            });
        }
        
        // 检查内存使用情况
        if (this.debugReport.resourceUsage.stackUsage === '高') {
            this.debugReport.warnings.push({
                type: '内存使用',
                description: '栈内存使用率较高',
                details: '当前栈内存使用率超过80%'
            });
            
            this.debugReport.recommendations.push({
                type: '内存优化',
                description: '建议调整任务栈深度',
                action: '在sdkconfig中增加CONFIG_ESP_MAIN_TASK_STACK_SIZE值'
            });
        }
    }

    /**
     * 检查GPIO冲突
     */
    checkGPIOConflicts(pinConfigurations) {
        const conflicts = [];
        
        // 这里应该实现实际的冲突检测逻辑
        // 简化示例：检查是否有重复的引脚配置
        const usedPins = new Set();
        Object.keys(pinConfigurations).forEach(pin => {
            if (usedPins.has(pin)) {
                conflicts.push(`引脚GPIO${pin}被多次配置`);
            }
            usedPins.add(pin);
        });
        
        return conflicts;
    }

    /**
     * 根据调试结果优化项目文件
     */
    async optimizeProjectFiles() {
        if (!this.debugReport) return;
        
        try {
            // 获取当前项目文件
            let projectFiles = this.state.getProjectFiles();
            
            // 根据调试报告中的建议优化项目文件
            for (const recommendation of this.debugReport.recommendations) {
                switch (recommendation.type) {
                    case 'GPIO优化':
                        // GPIO优化建议已在UI中提示，由用户手动处理
                        break;
                        
                    case '内存优化':
                        // 更新sdkconfig文件
                        if (projectFiles['sdkconfig']) {
                            let sdkconfig = projectFiles['sdkconfig'];
                            // 添加或修改内存相关配置
                            if (!sdkconfig.includes('CONFIG_ESP_MAIN_TASK_STACK_SIZE')) {
                                sdkconfig += '\nCONFIG_ESP_MAIN_TASK_STACK_SIZE=4096\n';
                                projectFiles['sdkconfig'] = sdkconfig;
                            }
                        }
                        break;
                }
            }
            
            // 更新项目状态
            this.state.setProjectFiles(projectFiles);
            
            // 更新UI
            this.ui.updateFileStructure();
            this.ui.showAlert('项目文件已根据调试结果优化', 'success');
            
            return projectFiles;
        } catch (error) {
            this.ui.showAlert(`优化项目文件失败: ${error.message}`, 'error');
            return null;
        }
    }

    /**
     * 获取调试状态
     */
    getStatus() {
        return {
            isConnected: this.isConnected,
            isDebugging: this.isDebugging,
            breakpoints: Array.from(this.breakpoints.values()),
            executionPath: this.executionPath
        };
    }
}